home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-13 / pasledit.zip / EDITOR.PAS < prev    next >
Pascal/Delphi Source File  |  1991-01-17  |  16KB  |  459 lines

  1. (*
  2.    Simple line editor program.  Written in Standard Pascal.
  3.  
  4.    By Ilya Shlyakhter, D-block
  5. *)
  6.  
  7. PROGRAM LineEditor (Input, Output);
  8.  
  9.    USES Strings;
  10.  
  11.    CONST NameCount = 10;
  12.          MaxNameLength = 30;
  13.  
  14.    TYPE NameArray = ARRAY [1..NameCount] OF StrType;
  15.         NameCountType = 0..NameCount;
  16.         NameLengthType = 0..MaxNameLength;
  17.  
  18.         Digit = 0..9;
  19.  
  20.    VAR NameData: NameArray;
  21.  
  22.  
  23.    FUNCTION UpCaseChar (Ch: Char): Char;
  24.  
  25.    (*
  26.        Converts a character to uppercase.
  27.    *)
  28.  
  29.       BEGIN  (* UpCaseChar *)
  30.          IF Ch IN ['a'..'z'] THEN
  31.             Ch := Chr (Ord (Ch) - Ord ('a') + Ord ('A'));
  32.  
  33.          UpCaseChar := Ch
  34.       END;   (* UpCaseChar *)
  35.  
  36.    FUNCTION ChrDigit (Ch: Char): Digit;
  37.  
  38.       BEGIN   (* ChrDigit *)
  39.          ChrDigit := Ord (Ch) - Ord ('0')
  40.       END;    (* ChrDigit *)
  41.  
  42.    PROCEDURE FlushLine;
  43.       
  44.       VAR Ch: Char;
  45.  
  46.       BEGIN  (* FlushLine *)
  47.          WHILE NOT (Eof OR Eoln) DO
  48.             Read (Ch);
  49.  
  50.          ReadLn
  51.       END;   (* FlushLine *)
  52.  
  53.  
  54.    PROCEDURE ReadNames (VAR Names: NameArray);
  55.  
  56.       VAR CurrentNameNum: NameCountType;
  57.  
  58.       PROCEDURE InputName (VAR Name: StrType);
  59.  
  60.          VAR CurrentCharNum: NameLengthType;
  61.              Ch: Char;
  62.  
  63.          BEGIN  (* InputName *)
  64.             StrInit (Name);
  65.             CurrentCharNum := 1;
  66.  
  67.             WHILE NOT Eof AND NOT Eoln AND (CurrentCharNum <= MaxnameLength) DO
  68.                BEGIN  (* read name *)
  69.                   Read (Ch);
  70.                   StrAddChar (Name, Ch);
  71.                   CurrentCharNum := CurrentCharNum + 1
  72.                END;   (* read name *)
  73.  
  74.             ReadLn
  75.          END;   (* InputName *)
  76.  
  77.       BEGIN  (* ReadNames *)
  78.          FOR CurrentNameNum := 1 TO NameCount DO
  79.             BEGIN  (* read *)
  80.                WriteLn;
  81.                Write ('Please enter name #',CurrentNameNum,': ');
  82.                InputName (Names [CurrentnameNum])
  83.             END;   (* read *)
  84.       END;   (* ReadNames *)
  85.  
  86.  
  87.    PROCEDURE DisplayNames (Names: NameArray);
  88.  
  89.       VAR I: Integer;
  90.  
  91.       BEGIN  (* DisplayNames *)
  92.          WriteLn;
  93.          WriteLn ('You have entered the following names:');
  94.          WriteLn;
  95.  
  96.          FOR I := 1 TO NameCount DO
  97.             BEGIN
  98.                Write (I,' - ');
  99.                StrDisplayString (Names [I])
  100.             END;
  101.  
  102.          WriteLn;
  103.       END;   (* DisplayNames *)
  104.  
  105.    PROCEDURE ProcessNames (Names: NameArray);
  106.  
  107.       VAR NameNum: NameCountType;
  108.           Done: Boolean;
  109.  
  110.  
  111.       PROCEDURE EditString (VAR TheString: StrType);
  112.  
  113.          VAR Done: Boolean;
  114.              Ch: Char;
  115.  
  116.          PROCEDURE DisplayHelp;
  117.  
  118.             VAR Ch: Char;
  119.  
  120.             BEGIN  (* DisplayHelp *)
  121.  
  122.                FlushLine;
  123.                WriteLn;
  124.  
  125.                WriteLn ('                EDITOR COMMANDS                                                ');
  126.                WriteLn ('                                                                               ');
  127.                WriteLn (' Icn           Insert character c at position n                              ');
  128.                WriteLn ('                                                                               ');
  129.                WriteLn (' DPn           Delete character at POSITION n                                ');
  130.                WriteLn (' DFc           Delete FIRST occurence of the character c                     ');
  131.                WriteLn ('                                                                               ');
  132.                WriteLn (' RPcn          Replace the character at POSITION n with character c          ');
  133.                WriteLn (' RFcd          Replace the FIRST occurence of character c with character d ');
  134.                WriteLn (' RAcd          Replace ALL  occurences of character c with character d     ');
  135.                WriteLn ('                                                                               ');
  136.                WriteLn (' H, ?          Display this help screeen                                     ');
  137.                WriteLn (' Q             Quit                                                          ');
  138.             END;   (* DisplayHelp *)
  139.  
  140.  
  141.          PROCEDURE ReadPos (VAR Value: StrLengthType; VAR Error: Boolean);
  142.  
  143.             VAR Ch: Char;
  144.                 CurrentValue: Integer;
  145.                 Digits: SET OF Char;
  146.                 Factor: Integer;
  147.                 MaxFactor: Integer;
  148.  
  149.             BEGIN  (* ReadPos *)
  150.                Digits := ['0'..'9'];
  151.                Error := False;
  152.  
  153.                IF Eof OR Eoln THEN
  154.                   Error := True
  155.                      ELSE
  156.                         BEGIN  (* there is text to read *)
  157.                            CurrentValue := 0;
  158.                            Factor := 1;
  159.  
  160.                            MaxFactor := 1;
  161.                            WHILE (MaxStrLength DIV MaxFactor) > 0 DO
  162.                               MaxFactor := MaxFactor * 10;
  163.  
  164.  
  165.                            WHILE NOT (Eof OR Eoln OR Error OR (Factor > MaxFactor)) DO
  166.                               BEGIN  (* process number *)
  167.                                  Read (Ch);
  168.                                  IF Ch IN Digits THEN
  169.                                     CurrentValue := CurrentValue + ChrDigit (Ch) * Factor
  170.                                        ELSE
  171.                                           Error := True
  172.                               END;   (* process number *)
  173.                         END;   (* there is text to read *)
  174.  
  175.                IF NOT Error THEN
  176.                   Value := CurrentValue
  177.  
  178.             END;   (* ReadPos *)
  179.  
  180.          PROCEDURE ReportError;
  181.  
  182.             VAR Ch: Char;
  183.  
  184.             BEGIN  (* ReportError *)
  185.  
  186.                FlushLine;
  187.                WriteLn;
  188.                WriteLn ('Input error. Try again.');
  189.                WriteLn
  190.             END;   (* ReportError *)
  191.  
  192.          PROCEDURE ProcessDelete;
  193.  
  194.             VAR Ch: Char;
  195.  
  196.             PROCEDURE ProcessDelPos;
  197.  
  198.                VAR Position: StrLengthType;
  199.                    Error: Boolean;
  200.  
  201.                BEGIN  (* ProcessDelPos *)
  202.                   ReadPos (Position, Error);
  203.  
  204.                   IF Error THEN 
  205.                      ReportError
  206.                         ELSE
  207.                            BEGIN
  208.                               StrDeleteCharPos (TheString, Position);
  209.                               FlushLine
  210.                            END
  211.                END;   (* ProcessDelPos *)
  212.  
  213.             PROCEDURE ProcessDelFirst;
  214.  
  215.                VAR Position: StrLengthType;
  216.                    Ch: Char;
  217.  
  218.                BEGIN  (* ProcessDelFirst *)
  219.                  IF NOT (Eof OR Eoln) THEN 
  220.                    BEGIN  (* process parameter *)
  221.                      Read (Ch);
  222.                      StrDeleteCharFirst (TheString, Ch);
  223.                      FlushLine
  224.                    END    (* process parameter *)
  225.                      ELSE
  226.                         ReportError;
  227.  
  228.                END;   (* ProcessDelFirst *)
  229.  
  230.             BEGIN  (* ProcessDelete *)
  231.                IF Eof OR Eoln THEN
  232.                   ReportError
  233.                      ELSE
  234.                         BEGIN
  235.                            Read (Ch);  (* read Delete subfunction *)
  236.  
  237.                            CASE UpCaseChar (Ch) OF
  238.                               'P': ProcessDelPos;
  239.                               'F': ProcessDelFirst;
  240.  
  241.                               ELSE
  242.                                  ReportError
  243.                            END  (* case *)
  244.                         END;
  245.  
  246.             END;   (* ProcessDelete *)
  247.  
  248.          PROCEDURE ProcessInsert;
  249.  
  250.             VAR Position: StrLengthType;
  251.                 VAR Ch: Char;
  252.                 Error: Boolean;
  253.  
  254.             BEGIN  (* ProcessInsert *)
  255.               IF Eof OR Eoln THEN
  256.                 ReportError
  257.                   ELSE
  258.                      BEGIN  (* at least 1 parameter given *)
  259.                         Read (Ch);
  260.                         IF Eof OR Eoln THEN
  261.                            ReportError
  262.                               ELSE
  263.                                  BEGIN  (* read position *)
  264.                                     ReadPos (Position, Error);
  265.                                     IF Error THEN
  266.                                        ReportError
  267.                                           ELSE
  268.                                              BEGIN  (* everything ok *)
  269.                                                 StrInsertChar (TheString, Ch, Position);
  270.                                                 FlushLine
  271.                                              END    (* everything ok *)
  272.                                  END;   (* read position *)
  273.                      END;   (* at least 1 parameter given *)
  274.  
  275.             END;   (* ProcessInsert *)
  276.  
  277.          PROCEDURE ProcessReplace;
  278.  
  279.             VAR ReplaceType: Char;
  280.  
  281.             PROCEDURE ProcessReplacePos;
  282.  
  283.                VAR Ch: Char;
  284.                    Position: StrLengthType;
  285.                    Error: Boolean;
  286.             
  287.                BEGIN  (* ProcessReplacePos *)
  288.                   IF Eof OR Eoln THEN
  289.                      ReportError
  290.                         ELSE
  291.                            BEGIN  (* at least 1 parameter given *)
  292.                               Read (Ch);
  293.                               IF Eof OR Eoln THEN
  294.                                  ReportError
  295.                                     ELSE
  296.                                        BEGIN  (* at least 2 parameters given *)
  297.                                           ReadPos (Position, Error);
  298.                                           IF Error THEN
  299.                                              ReportError
  300.                                                 ELSE
  301.                                                    BEGIN  (* everything ok *)
  302.                                                       StrReplaceCharPos (TheString, Ch, Position);
  303.                                                       FlushLine
  304.                                                    END    (* everything ok *)
  305.  
  306.                                        END;   (* at least 2 parameters given *)
  307.                            END;   (* at least 1 parameter given *)
  308.                END;   (* ProcessReplacePos *)
  309.  
  310.             PROCEDURE ProcessReplaceFirst;
  311.  
  312.                VAR OldChar, NewChar: Char;
  313.  
  314.                BEGIN  (* ProcessReplaceFirst *)
  315.                   IF Eof OR Eoln THEN
  316.                      ReportError
  317.                         ELSE
  318.                            BEGIN  (* source character given *)
  319.                               Read (OldChar);
  320.                               IF Eof OR Eoln THEN
  321.                                  ReportError
  322.                                     ELSE
  323.                                        BEGIN  (* target character given *)
  324.                                           Read (NewChar);
  325.                                           StrReplaceCharFirst (TheString, OldChar, NewChar);
  326.                                           FlushLine
  327.                                        END    (* target character given *)
  328.                            END;   (* source character given *)
  329.                END;   (* ProcessReplaceFirst *)
  330.  
  331.             PROCEDURE ProcessReplaceAll;
  332.  
  333.                VAR OldChar, NewChar: Char;
  334.  
  335.                BEGIN  (* ProcessReplaceAll *)
  336.                   IF Eof OR Eoln THEN
  337.                      ReportError
  338.                         ELSE
  339.                            BEGIN  (* source character given *)
  340.                               Read (OldChar);
  341.                               IF Eof OR Eoln THEN
  342.                                  ReportError
  343.                                     ELSE
  344.                                        BEGIN  (* target character given *)
  345.                                           Read (NewChar);
  346.                                           StrReplaceCharAll (TheString, OldChar, NewChar);
  347.                                           FlushLine
  348.                                        END    (* target character given *)
  349.                            END;   (* source character given *)
  350.  
  351.  
  352.                END;   (* ProcessReplaceAll *)
  353.  
  354.             BEGIN  (* ProcessReplace *)
  355.               IF Eof OR Eoln THEN
  356.                   ReportError
  357.                      ELSE
  358.                         BEGIN  (* there is more input to read *)
  359.                            Read (ReplaceType);
  360.  
  361.                            CASE UpCaseChar (ReplaceType) OF
  362.                               
  363.                               'P':  ProcessReplacePos;
  364.                               'F':  ProcessReplaceFirst;
  365.                               'A':  ProcessReplaceAll
  366.                                  ELSE
  367.                                     ReportError;
  368.                            END;  (* case *)
  369.  
  370.                         END;   (* there is more input to read *)
  371.                
  372.             END;   (* ProcessReplace *)
  373.  
  374.          PROCEDURE ProcessAppend;
  375.  
  376.             VAR Ch: Char;
  377.          
  378.             BEGIN  (* ProcessAppend *)
  379.                IF Eof OR Eoln THEN
  380.                   ReportError
  381.                      ELSE
  382.                         BEGIN  (* process parameter *)
  383.                            Read (Ch);
  384.                            StrAddChar (TheString, Ch);
  385.                            FlushLine
  386.                         END;   (* process parameter *)
  387.  
  388.  
  389.             END;   (* ProcessAppend *)
  390.  
  391.  
  392.          BEGIN  (* EditString *)
  393.             WriteLn;
  394.  
  395.             Done := False;
  396.  
  397.             WHILE NOT Done DO
  398.                BEGIN  (* edit string *)
  399.                   WriteLn;
  400.                   StrDisplayString (TheString);
  401.                   WriteLn ('The name is now ',StrLength (TheString),' characters long.');
  402.                   WriteLn;
  403.                   Write ('Enter command: ');
  404.  
  405.                   IF Eof OR Eoln THEN
  406.                      ReportError
  407.                         ELSE
  408.                            BEGIN  (* the user entered something *)
  409.                               Read (Ch);
  410.  
  411.                               CASE UpCaseChar (Ch) OF
  412.                                  'D':  ProcessDelete;
  413.                                  'I':  ProcessInsert;
  414.                                  'R':  ProcessReplace;
  415.                                  'A':  ProcessAppend;
  416.                                  'H':  DisplayHelp;
  417.                                  'Q':  Done := True
  418.  
  419.                               END;  (* case *)
  420.  
  421.  
  422.  
  423.  
  424.                            END;   (* the user entered something *)
  425.  
  426.  
  427.                END;   (* edit string *)
  428.  
  429.  
  430.          END;   (* EditString *)
  431.  
  432.       BEGIN  (* ProcessNames *)
  433.  
  434.          Done := False;
  435.  
  436.          REPEAT
  437.             REPEAT
  438.                WriteLn;
  439.                Write ('Enter the number of name to revise (1 through ',NameCount,', 0 to quit): ');
  440.                ReadLn (NameNum);
  441.             UNTIL NameNum <= NameCount;
  442.  
  443.             IF NameNum = 0 THEN
  444.                Done := True
  445.                   ELSE
  446.                      EditString (Names [NameNum])
  447.          UNTIL Done;
  448.  
  449.          WriteLn
  450.       END;   (* ProcessNames *)
  451.  
  452.  
  453.    BEGIN  (* LineEditor *)
  454.       ReadNames (NameData);
  455.  
  456.       DisplayNames (NameData);
  457.       ProcessNames (NameData)
  458.    END.   (* LineEditor *)
  459.